/*
Copyright (C) 2011 Diego Darriba, David Posada
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package es.uvigo.darwin.jmodeltest.gui;
import java.awt.FileDialog;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.border.LineBorder;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.BorderUIResource.TitledBorderUIResource;
import es.uvigo.darwin.jmodeltest.ModelTest;
import es.uvigo.darwin.jmodeltest.ModelTestConfiguration;
import es.uvigo.darwin.jmodeltest.utilities.Utilities;
public class FramePreferences extends JModelTestFrame {
private static final int WINDOW_WIDTH = 500;
private static final int OUTER_MARGIN = 10;
private static final int MARGIN = 20;
private static final int COMPONENTS_WIDTH = WINDOW_WIDTH - 2 * OUTER_MARGIN;
private static final int COMPONENTS_HEIGHT = 20;
private static final int MAX_INNER_WIDTH = COMPONENTS_WIDTH - 2 * MARGIN;
private static final int BINARIES_PANEL_HEIGHT = MARGIN + 6
* COMPONENTS_HEIGHT + OUTER_MARGIN;
private static final int BUTTONS_RESET_WIDTH = 140;
private static final int BUTTONS_WIDTH = 110;
private static final int BUTTONS_HEIGHT = 40;
private static final int BUTTONS_PADDING = 10;
private static final int BUTTONS_PANEL_WIDTH = BUTTONS_RESET_WIDTH + 2 * BUTTONS_WIDTH + 2 * BUTTONS_PADDING;
private static final int BUTTONS_VLOC = BINARIES_PANEL_HEIGHT;
private static final int BUTTONS_HLOC = (COMPONENTS_WIDTH - BUTTONS_PANEL_WIDTH)/2;
private static final int WINDOW_HEIGHT = 250;
private static final long serialVersionUID = 1L;
private static final String BACKUP_FILE = ModelTest.CONFIG_FILE + ".bk";
private static final String BINARIES_COMMENT = "Set the phyml binary directory. The selected directory "
+ "should exist and contain a valid phyml binary (\"phyml\" or \""+ Utilities.getBinaryVersion()+"\"). If Global "
+ "Phyml checkbox is selected, \"phyml\" should exist in the path.";
private static final String PROPERTIES_COMMENT = "This properties file was modified from "
+ "jModelTest 2 GUI. A backup of the original configuration file has been "
+ "stored in "
+ BACKUP_FILE
+ ". Replace this file with the backup for "
+ "restoring the original format.";
private JTextArea tfBinaryDescription = new JTextArea();
private JCheckBox cbGlobalPhyml = new JCheckBox();
private JLabel lbPathToPhyml = new JLabel();
private JTextField tfPathToPhyml = new JTextField();
private JPanel binarySettingsPanel = new JPanel();
private JPanel buttonsPanel = new JPanel();
private JPanel preferencesPanel = new JPanel();
private JButton btnSetDefault = new JButton();
private JButton btnAccept = new JButton();
private JButton btnCancel = new JButton();
private JButton btnOpen;
public FramePreferences() {
initComponents();
}
public void initComponents() {
preferencesPanel.setLocation(0, 0);
preferencesPanel.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
preferencesPanel.setVisible(true);
preferencesPanel.setLayout(null);
binarySettingsPanel.setLocation(OUTER_MARGIN, OUTER_MARGIN);
binarySettingsPanel.setSize(COMPONENTS_WIDTH, BINARIES_PANEL_HEIGHT);
binarySettingsPanel
.setBorder(new BorderUIResource.TitledBorderUIResource(
new LineBorder(XManager.PANEL_BORDER_COLOR, 1, false),
"PhyML Binaries Settings", TitledBorderUIResource.LEFT,
TitledBorderUIResource.TOP, XManager.FONT_LABEL,
XManager.LABEL_BLUE_COLOR));
binarySettingsPanel.setVisible(true);
binarySettingsPanel.setLayout(null);
buttonsPanel.setLocation(BUTTONS_HLOC, BUTTONS_VLOC);
buttonsPanel.setSize(COMPONENTS_WIDTH, BINARIES_PANEL_HEIGHT);
buttonsPanel.setVisible(true);
buttonsPanel.setLayout(null);
tfBinaryDescription.setVisible(true);
tfBinaryDescription.setEditable(false);
tfBinaryDescription.setOpaque(false);
tfBinaryDescription.setForeground(XManager.DARK_GRAY_COLOR);
tfBinaryDescription.setSize(MAX_INNER_WIDTH, 3 * COMPONENTS_HEIGHT);
tfBinaryDescription.setLocation(MARGIN, MARGIN);
tfBinaryDescription.setText(BINARIES_COMMENT);
tfBinaryDescription.setFont(XManager.FONT_LABEL);
tfBinaryDescription.setLineWrap(true);
tfBinaryDescription.setWrapStyleWord(true);
cbGlobalPhyml.setVisible(true);
cbGlobalPhyml.setSize(MAX_INNER_WIDTH, COMPONENTS_HEIGHT);
cbGlobalPhyml.setText("Use global PhyML binary");
cbGlobalPhyml.setLocation(MARGIN, 3 * COMPONENTS_HEIGHT + MARGIN);
cbGlobalPhyml.setFont(XManager.FONT_LABEL);
lbPathToPhyml.setVisible(true);
lbPathToPhyml.setSize(120, COMPONENTS_HEIGHT);
lbPathToPhyml.setText("PhyML binary path:");
lbPathToPhyml.setLocation(2 * MARGIN, MARGIN + 4 * COMPONENTS_HEIGHT);
lbPathToPhyml.setFont(XManager.FONT_LABEL);
tfPathToPhyml.setVisible(true);
tfPathToPhyml.setSize(280, COMPONENTS_HEIGHT);
tfPathToPhyml.setLocation(2 * MARGIN + 120, MARGIN + 4 * COMPONENTS_HEIGHT);
tfPathToPhyml.setFont(XManager.FONT_LABEL);
btnOpen = XManager.makeIconButton("Open16", "Explore", "...");
btnOpen.setLocation(2 * MARGIN + 400, MARGIN + 4 * COMPONENTS_HEIGHT);
btnSetDefault.setText("Default Settings");
btnSetDefault.setLocation(0, MARGIN);
btnSetDefault.setSize(BUTTONS_RESET_WIDTH, BUTTONS_HEIGHT);
btnSetDefault.setVisible(true);
btnCancel.setText("Cancel");
btnCancel.setLocation(BUTTONS_RESET_WIDTH+BUTTONS_PADDING, MARGIN);
btnCancel.setSize(BUTTONS_WIDTH, BUTTONS_HEIGHT);
btnCancel.setVisible(true);
btnAccept.setText("Accept");
btnAccept.setLocation(BUTTONS_RESET_WIDTH + BUTTONS_WIDTH+2*BUTTONS_PADDING, MARGIN);
btnAccept.setSize(BUTTONS_WIDTH, BUTTONS_HEIGHT);
btnAccept.setVisible(true);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setResizable(false);
binarySettingsPanel.add(tfBinaryDescription);
binarySettingsPanel.add(tfPathToPhyml);
binarySettingsPanel.add(btnOpen);
binarySettingsPanel.add(cbGlobalPhyml);
binarySettingsPanel.add(lbPathToPhyml);
buttonsPanel.add(btnSetDefault);
buttonsPanel.add(btnAccept);
buttonsPanel.add(btnCancel);
preferencesPanel.add(binarySettingsPanel);
preferencesPanel.add(buttonsPanel);
getContentPane().setLayout(null);
getContentPane().add(preferencesPanel);
setTitle("Preferences");
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setLocation(XManager.MAIN_LOCATION);
getRootPane().setDefaultButton(btnAccept);
setStatus();
cbGlobalPhyml.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
globalPhymlActionPerformed(e);
}
});
btnSetDefault.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
cbGlobalPhyml
.setSelected(ModelTestConfiguration.DEFAULT_GLOBAL_PHYML);
tfPathToPhyml.setText(ModelTestConfiguration.DEFAULT_EXE_DIR);
tfPathToPhyml.setEnabled(!cbGlobalPhyml.isSelected());
}
});
btnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
cancelActionPerformed(e);
}
});
btnAccept.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
acceptActionPerformed(e);
}
});
btnOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
exploreActionPerformed(e);
}
});
}
private void setStatus() {
cbGlobalPhyml.setSelected(ModelTestConfiguration.isGlobalPhymlBinary());
tfPathToPhyml.setText(ModelTestConfiguration.getExeDir());
tfPathToPhyml.setEnabled(!cbGlobalPhyml.isSelected());
}
private void cancelActionPerformed(java.awt.event.ActionEvent e) {
try {
setStatus();
setVisible(false);
dispose();
} catch (Exception f) {
f.printStackTrace();
}
}
private void acceptActionPerformed(java.awt.event.ActionEvent e) {
try {
// validate changes
boolean validated = true;
if (!cbGlobalPhyml.isSelected()) {
File testBinDir = new File(tfPathToPhyml.getText());
if (validated = (testBinDir.exists() && testBinDir
.isDirectory())) {
String path = tfPathToPhyml.getText();
if (!path.endsWith(File.separator)) {
path += File.separator;
}
File localExe = new File(path
+ Utilities.getBinaryVersion());
File genericExe = new File(path + "phyml");
validated = (localExe.exists() && localExe.isFile() && localExe
.canExecute())
|| (genericExe.exists() && genericExe.isFile() && genericExe
.canExecute());
}
}
if (validated) {
// update properties file
Properties properties = ModelTestConfiguration.getProperties();
properties.setProperty(ModelTestConfiguration.EXE_DIR,
tfPathToPhyml.getText());
properties.setProperty(ModelTestConfiguration.GLOBAL_PHYML_EXE,
cbGlobalPhyml.isSelected() ? "true" : "false");
writeProperties();
setVisible(false);
dispose();
} else {
JOptionPane
.showMessageDialog(
this,
"There is no phyml binary in the selected location. \n"
+ "Please make sure that exists an executable file named\n"
+ "\"phyml\" or "
+ Utilities.getBinaryVersion() + ".",
"jModelTest error", JOptionPane.ERROR_MESSAGE);
return;
}
} catch (Exception f) {
f.printStackTrace();
}
}
private void globalPhymlActionPerformed(java.awt.event.ActionEvent e) {
try {
tfPathToPhyml.setEnabled(!cbGlobalPhyml.isSelected());
} catch (Exception f) {
f.printStackTrace();
}
}
private void exploreActionPerformed(java.awt.event.ActionEvent e) {
FileDialog dialog;
try {
try {
dialog = new FileDialog(this, "Select PhyML binaries directory",
FileDialog.LOAD);
dialog.setDirectory(ModelTestConfiguration.DEFAULT_EXE_DIR);
dialog.setVisible(true);
} catch (Throwable f) {
f.printStackTrace();
return;
}
tfPathToPhyml.setText(dialog.getDirectory());
} catch (Exception f) {
f.printStackTrace();
}
}
private void writeProperties() {
Properties properties = ModelTestConfiguration.getProperties();
try {
File bkFile = new File(BACKUP_FILE);
if (!bkFile.exists()) {
File propertiesFile = new File(ModelTest.CONFIG_FILE);
InputStream in = new FileInputStream(propertiesFile);
OutputStream out = new FileOutputStream(bkFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
// Escribier en el archivo los cambios
FileOutputStream fos = new FileOutputStream(
ModelTest.CONFIG_FILE.replace("\\", "/"));
properties.store(fos, PROPERTIES_COMMENT);
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}